﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace TotalApplication.Core
{
    public partial class ChatMessageListViewModel : BaseViewModel
    {
        #region Protected Properties

        /// <summary>
        /// The last searched text in the list
        /// </summary>
        protected string? _lastSearchText;

        /// <summary>
        /// The text to search for in the search command
        /// </summary>
        protected string? _searchText;

        /// <summary>
        /// The chat thread items for the list
        /// </summary>
        protected ObservableCollection<ChatMessageListItemViewModel>? _items;

        /// <summary>
        /// The chat thread items for the list AFTER Filtered
        /// </summary>
        protected ObservableCollection<ChatMessageListItemViewModel>? _filteredItems;

        /// <summary>
        /// A flag indicating if the search dialog is opened
        /// </summary>
        [ObservableProperty]
        protected bool _isSearchOpen;

        partial void OnIsSearchOpenChanged(bool oldValue, bool newValue)
        {
            if (oldValue == newValue) return;
            oldValue = newValue;

            // If dialog closes, clear search text
            if (!oldValue)
                SearchText = string.Empty;
        }


        #endregion

        #region Public properties

        /// <summary>
        /// The chat thread items for the list
        /// NOTE: Don't call Items.Add to add message to the list
        ///       as it will make the FilteredItems out of sync
        /// </summary>
        public ObservableCollection<ChatMessageListItemViewModel> Items
        {
            get => _items ?? new ObservableCollection<ChatMessageListItemViewModel>();
            set
            {
                if (_items == value) return;
                _items = value;

                // Update filter list to match
                FilteredItems = new ObservableCollection<ChatMessageListItemViewModel>(_items);
                OnPropertyChanged(nameof(Items));
            }
        }

        /// <summary>
        /// The chat thread items for the list include any search filtering
        /// </summary>
        public ObservableCollection<ChatMessageListItemViewModel>? FilteredItems
        {
            get => _filteredItems;
            set
            {
                if (_filteredItems == value) return;
                _filteredItems = value;  

                // Update filter list to match

                OnPropertyChanged(nameof(FilteredItems));

            }
        }

        /// <summary>
        /// The visibility of the Attachment Popup Menu
        /// </summary>
        [ObservableProperty]
        private bool _attachmentMenuVisible = false;

        /// <summary>
        /// The ViewModel for the Attachment Popup Menu
        /// </summary>
        public ChatAttachmentPopupMenuViewModel AttachmentMenu { get; set; } = new ChatAttachmentPopupMenuViewModel();

        /// <summary>
        /// The text for the current message being written
        /// </summary>
        [ObservableProperty]
        private string _pendingMessageText = string.Empty;

        [ObservableProperty]
        private string _displayTitle = "TZJ_lll";

        public string SearchText
        {
            get => _searchText ?? string.Empty;
            set
            {
                if(_searchText == value) return;
                _searchText = value;

                // If empty or null, search to restore message
                if (string.IsNullOrEmpty(SearchText))
                    Search();

                OnPropertyChanged(nameof(SearchText));
            }
        }


        #endregion

        #region Public Commands

        /// <summary>
        /// When the Attachment button is clicked, turn on the visibility of the Attachment Menu
        /// </summary>
        [RelayCommand]
        private void AttachmentButton()
        {
            AttachmentMenuVisible = true;
        }

        /// <summary>
        /// When the popup clickaway area is clicked, turn off the visibility of the Attachment Menu
        /// </summary>
        [RelayCommand]
        private void PopupClick()
        {
            AttachmentMenuVisible = false;
        }

        /// <summary>
        /// When the user clicks the Send button, sends message
        /// </summary>
        [RelayCommand]
        public void Send()
        {
            if(FilteredItems == null)
                FilteredItems = new ObservableCollection<ChatMessageListItemViewModel>();

            // Fake send a message
            var message = new ChatMessageListItemViewModel
            {
                SenderName = "Luke",
                Message = PendingMessageText,
                MessageSentTime = DateTimeOffset.UtcNow,
                SentByMe = true,
                Initial = "LM",
                NewItem = true,
            };

            // Add message to both list
            Items.Add(message);
            FilteredItems.Add(message);

            // Clear Pending Text
            PendingMessageText = string.Empty;
        }

        [RelayCommand]
        private void Search()
        {
            // Make sure we don't re-search the same text
            if ((string.IsNullOrEmpty(_lastSearchText)) && (string.IsNullOrEmpty(SearchText)) || string.Equals(_lastSearchText, SearchText))
                return;

            // If we have no search text or no items
            if(string.IsNullOrEmpty(SearchText) || Items == null || Items.Count <= 0)
            {
                FilteredItems = new ObservableCollection<ChatMessageListItemViewModel>(Items ?? new ObservableCollection<ChatMessageListItemViewModel>());

                _lastSearchText = SearchText;

                return;
            }

            FilteredItems = new ObservableCollection<ChatMessageListItemViewModel>(
                Items.Where(item => (item.Message ?? string.Empty).ToLower().Contains(SearchText)));

            _lastSearchText = SearchText;
        }

        [RelayCommand]
        private void OpenSearch()
        {
            IsSearchOpen = true;
        }

        [RelayCommand]
        private void CloseSearch()
        {
            IsSearchOpen = false;
        }

        /// <summary>
        /// Clear the search text OR Close Dialog
        /// </summary>
        [RelayCommand]
        private void ClearSearch()
        {
            if(!string.IsNullOrEmpty(SearchText)) 
                SearchText = string.Empty;
            else
            {
                IsSearchOpen = false;
            }

        }

        #endregion

        #region Constructor

        public ChatMessageListViewModel()
        {
            Items = new ObservableCollection<ChatMessageListItemViewModel>(){
                new ChatMessageListItemViewModel
                {
                    SenderName = "Parnell",
                    Message = "I'm about to wipe the old server, we need to update the old server to windows 2016",
                    Initial = "PL",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    SentByMe = false
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Luke",
                    Message = "Let me know when you manage to sign up the new 2016 server",
                    Initial = "LM",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    MessageReadTime = DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(1.3)),
                    SentByMe = true
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Parnell",
                    Message = "The new server is upo. Go to 192.168.1.1 Username is admin, password is P8ssawovd",
                    Initial = "PL",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    SentByMe = false
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Parnell",
                    Message = "I'm about to wipe the old server, we need to update the old server to windows 2016",
                    Initial = "PL",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    SentByMe = false
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Luke",
                    Message = "Let me know when you manage to sign up the new 2016 server",
                    Initial = "LM",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    MessageReadTime = DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(1.3)),
                    SentByMe = true
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Parnell",
                    Message = "The new server is upo. Go to 192.168.1.1 Username is admin, password is P8ssawovd",
                    Initial = "PL",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    SentByMe = false
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Parnell",
                    Message = "I'm about to wipe the old server, we need to update the old server to windows 2016",
                    Initial = "PL",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    SentByMe = false
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Luke",
                    Message = "Let me know when you manage to sign up the new 2016 server",
                    Initial = "LM",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    MessageReadTime = DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(1.3)),
                    SentByMe = true
                },
                new ChatMessageListItemViewModel
                {
                    SenderName = "Parnell",
                    Message = $"OSVersion: 【{Environment.OSVersion}】\r\nProcessorCount: 【{Environment.ProcessorCount}】\r\nUserDomainName: 【{Environment.UserDomainName}】\r\nThe new server is upo. Go to 192.168.1.1 Username is admin, password is P8ssawovd",
                    Initial = "PL",
                    ProfilePictureRGB = "3099c5",
                    MessageSentTime = DateTimeOffset.UtcNow,
                    SentByMe = false,
                    ImageAttachment = new ChatMessageListImageItemViewModel{ThumbnailUrl="/assets/img/example.png"}
                },
            };
        }


        #endregion

        #region Command Methods

        #endregion
    }
}
